<#include "macrosDisplay.ftl">
<#include "macrosLoops.ftl">
<#include "macroUtils.ftl">
<#include "tpsTypes.ftl">

package com.tps.gen.bo;

import java.util.*;
import javax.persistence.*;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Index;

import com.tps.type.*;
import com.tps.framework.util.*;

import com.tps.framework.annotation.Auditable;
import com.tps.framework.annotation.ClonePolicy;
import com.tps.framework.annotation.DisplayName;
import com.tps.framework.annotation.Evaluatable;
import com.tps.framework.annotation.RelationshipInfo;

import com.tps.framework.hibernate.AbstractHibernateEntity;

/**
 * <p>
 * Represents a(n) <@boCap/>.
 * </p>
 *
 * <p>${bo.description}</p>
 * 
 * <p>Created ${util.getDateString()}</p>
 * 
 * @author Archimedes
 * @version $Id: Entity.ftl 2893 2006-09-05 15:08:24 +0000 (Tue, 05 Sep 2006) erik $
 */
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate=true, dynamicInsert=true)
@Table(name = "x<@boLow/>")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "classtype", length = 64, discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("com.tps.gen.bo.<@boCap/>")
<@auditable bo>@Auditable</@auditable>
<@evaluatable bo>@Evaluatable</@evaluatable>
@DisplayName(name = "${bo.displayName}")
public <@isAbstract bo>abstract</@isAbstract> class <@boCap/> extends <@extends bo /> <@interface bo /> {

    /**
     * Fixed serial version UID to keep serialization working properly
     */
    private static final long serialVersionUID = 1L;

	// Regular Members
<@concreteMemberLoop><@isNotInherited bo, member>
    private <@meType/> <@meLow/> = <@defaultMember member/></@isNotInherited></@concreteMemberLoop>   

	// Enumeration Members
<@enumMemberLoop><@isNotInherited bo, member>
    private ${member.enumName} <@meLow/> = ${member.defaultValue};</@isNotInherited></@enumMemberLoop>

	// OneToMany Members   
<@OTMRelationshipsLoop><@isNotInherited bo, relation><#if !util.isInheritedRelation(relation)>
	private List<<@childCap/>> <@pluralUncap relation.aliasTarget/> = new ArrayList<<@childCap/>>();</#if></@isNotInherited></@OTMRelationshipsLoop>
<@OTMRelationshipsLoopInverse><@isNotInherited bo, relation><#if !util.isInheritedRelation(relation)>
	private <@parentCap/> <@uncap relation.aliasSource/> = null;</#if></@isNotInherited></@OTMRelationshipsLoopInverse>  

	// ManyToOne Members    
<@MTORelationshipsLoop><@isNotInherited bo, relation>
	private <@childCap/> <@uncap relation.aliasTarget/> = null;</@isNotInherited></@MTORelationshipsLoop>	
<@MTOInverseRelationshipsLoop><@isNotInherited bo, relation>
	private List<<@parentCap/>> <@pluralUncap relation.aliasSource/> = new ArrayList<<@parentCap/>>();</@isNotInherited></@MTOInverseRelationshipsLoop>	

	// OneToOne Members   
<@OTORelationshipsLoop><@isNotInherited bo, relation>
	private <@childCap/> <@uncap relation.aliasTarget/> = null;</@isNotInherited></@OTORelationshipsLoop>	
<@OTOInverseRelationshipsLoop><@isNotInherited bo, relation>
	private <@parentCap/> <@uncap relation.aliasSource/> = null;</@isNotInherited></@OTOInverseRelationshipsLoop>		

	// ManyToMany Members   
<@MTMRelationshipsLoop><@isNotInherited bo, relation>
	<@isTarget bo, relation><@isBidirectional relation>private List<<@parentCap/>> <@pluralUncap relation.aliasSource/> = new ArrayList<<@parentCap/>>();</@isBidirectional></@isTarget>
	<@isSource bo, relation>private List<<@childCap/>> <@pluralUncap relation.aliasTarget/> = new ArrayList<<@childCap/>>();</@isSource>	
	</@isNotInherited></@MTMRelationshipsLoop>


<#-- Member Getters and Setters -->
<@concreteMemberLoop>
<@isNotInherited bo, member>
<#--Test and handle for TPS Types -->
<@tpsTypeBeanTest member/>
 
    /**
     * <p>Returns the <@meLow/>.</p>
     *
     * <p>${member.description}</p>
     *
     * @return <@meType/> value of <@meLow/>
     *
     <#if member.returnType?starts_with("com.tps") >
     * @hibernate.component prefix="<@meLow/>_"
     <#else>
     * @hibernate.property
     </#if>
     *
     */
    <#if member.returnType?starts_with("com.tps") >
	@Embedded
    </#if>
    <#if member.returnType = "java.lang.Boolean" >
    @Column(columnDefinition="BOOLEAN")
    </#if>
    @DisplayName(name = "<@meDisplay/>")
    <#if member.indexed >
    @Index(name="IDX_<@meAll/>")
    </#if>
    public <@meType/> get<@meCap/>() {
        return <@meLow/>;
    }

    /**
     * <p>Sets the <@meLow/></p>
     *
     * <p>${member.description}</p>
     *
     * @param <@meLow/> The <@meLow/> to set.
     */
    public void set<@meCap/>(<@meType/> <@meLow/>) {
        this.<@meLow/> = <@meLow/>;
    }
</@isNotInherited>   
</@concreteMemberLoop>

<#-- Enumerated-type Members -->
<@enumMemberLoop>
<@isNotInherited bo, member>
    /**
     * <p>Returns the <@meLow/>.</p>
     *
     * <p>${member.description}</p>
     *
     * @return ${member.enumName} value of <@meLow/>
     */
	@Enumerated(EnumType.STRING)
    @DisplayName(name = "<@meDisplay/>")
    public ${member.enumName} get<@meCap/>() {
        return <@meLow/>;
    }

    /**
     * <p>Sets the <@meLow/></p>
     *
     * <p>${member.description}</p>
     *
     * @param <@meLow/> The <@meLow/> to set.
     */
    public void set<@meCap/>(${member.enumName} <@meLow/>) {
        this.<@meLow/> = <@meLow/>;
    }
</@isNotInherited>
</@enumMemberLoop>
 
<#-- Alias Members -->
<@aliasMemberLoop>
<@isNotInherited bo, member>
    /**
     * <p>Returns the <@meLow/>.</p>
     *
     * <p>${member.description}</p>
     *
     * @return <@meType/> value of <@meLow/>
     */
    @Transient
    public <@meType/> get<@meCap/>() {
        return get<@meTargetCap/>();
    }
</@isNotInherited>  
</@aliasMemberLoop>

<@customStringMemberLoop>
<@isNotInherited bo, member>
    /** 
     * @see com.tps.framework.hibernate.AbstractHibernateEntity#get<@meCap/>()
     */
	@Transient
    public <@meType/> get<@meCap/>() {
        return EntityUtils.calculateString(this, "<@meCustomString/>");
    }
</@isNotInherited>  
</@customStringMemberLoop>

<@beanPathMemberLoop bo>
<@isNotInherited bo, member>
    /** 
     * Returns the object resulting from the path ${member.path}
     * @return the <@meType/> from path ${member.path}
     */
	@Transient
    public <@meType/> get<@meCap/>() {
        return EntityUtils.getBeanPath(<@meType/>.class, this, "${member.path}");
    }
</@isNotInherited>
</@beanPathMemberLoop>

<#-- M:M Start -->

<#-- Loop to handle Getters and Setters -->
<@MTMRelationshipsLoop>
<@isNotInherited bo, relation>
<#-- //MTM Loop for ${bo} with ${relation} -->
<#-- <M:M with BO in the Source position -->
<#-- <EXAMPLE Order(this) to Item, creates Order.getItems -->
<@isSource bo,relation>
    /**
     * Returns the <@pluralUncap relation.aliasTarget/>.
     *
     * @return List<<@childCap/>> value of <@pluralUncap relation.aliasTarget/>
     */
	@ManyToMany // TODO: these right?
	@JoinTable(name = "<@lower relation.aliasSource/>_<@lower relation.aliasTarget/>",
			joinColumns = { @JoinColumn(name = "<@uncap relation.aliasSource/>_guid") },
			inverseJoinColumns = { @JoinColumn(name = "<@uncap relation.aliasTarget/>_guid") } )
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@boCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@childCap/>.class, type = RelationshipInfo.TYPE.ManyToMany, direction = RelationshipInfo.DIRECTION.Bidirectional, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.Reference)
    public List<<@childCap/>> get<@pluralCap relation.aliasTarget/>() {
        return <@pluralUncap relation.aliasTarget/>;
    }

    /**
     * Sets the <@pluralUncap relation.aliasTarget/>.
     */
    public void set<@pluralCap relation.aliasTarget/>(List <<@childCap/>> <@pluralUncap relation.aliasTarget/>) {
        this.<@pluralUncap relation.aliasTarget/> = <@pluralUncap relation.aliasTarget/>;
    }
    
    /**
     * Adds one <@uncap relation.aliasTarget/> of type <@childCap/>
     * @param <@uncap relation.aliasTarget/> The <@uncap relation.aliasTarget/> to add.
     */
    public boolean add<@cap relation.aliasTarget/>(<@childCap/> <@uncap relation.aliasTarget/>) {
        return this.get<@pluralCap relation.aliasTarget/>().add(<@uncap relation.aliasTarget/>);   
    }
    
</@isSource>
<#-- <M:M with BO in the Target position-->
<#-- <EXAMPLE Order to Item (this), handles Item.getOrders-->
<@isTarget bo,relation><@isBidirectional relation>
    /**
     * Returns the <@pluralUncap relation.aliasSource/>.
     *
     * @return List value of <@pluralUncap relation.aliasSource/>
     */
    @ManyToMany(mappedBy = "<@pluralUncap relation.aliasTarget/>")
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@childCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@parentCap/>.class, type = RelationshipInfo.TYPE.ManyToMany, direction = RelationshipInfo.DIRECTION.Bidirectional, inverse = true, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.None)
    public List<<@parentCap/>> get<@pluralCap relation.aliasSource/>() {
        return this.<@pluralUncap relation.aliasSource/>;
    }
    
    public void set<@pluralCap relation.aliasSource/>(List<<@parentCap/>> <@pluralUncap relation.aliasSource/>) {
        this.<@pluralUncap relation.aliasSource/> = <@pluralUncap relation.aliasSource/>;
    }
    
</@isBidirectional></@isTarget></@isNotInherited></@MTMRelationshipsLoop>
<#-- M:M End -->

<#-- 1:M Start -->

<#-- Loop to handle Getters and Setters -->
<#-- <1:M with BO in the From position-->
<#-- <EXAMPLE Customer (this) to Order -->
<@OTMRelationshipsLoop>
<@isNotInherited bo, relation>
	/**
     * Returns the <@childLowPlural/>.
     *
     * @return List value of <@childLowPlural/>
     */
    <#if !util.isInheritedRelation(relation)>
    @OneToMany(cascade = { CascadeType.ALL })
	@JoinColumn(name = "<@uncap relation.aliasSource/>_<@uncap relation.aliasTarget/>_guid")
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
   	</#if>
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@cap relation.fromEntity.entityName />.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@cap relation.toEntity.entityName />.class, type = RelationshipInfo.TYPE.OneToMany, direction = RelationshipInfo.DIRECTION.Bidirectional, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.Traverse)
    <#if !util.isInheritedRelation(relation)>    
    public List<<@cap relation.toEntity.entityName />> get<@pluralCap relation.aliasTarget/>() {
        return <@pluralUncap relation.aliasTarget/>;
    }
	<#else>
	@Transient
    public List<<@cap relation.parentRelationship.toEntity.entityName />> get<@pluralCap relation.parentRelationship.aliasTarget/>() {
        return super.get<@pluralCap relation.parentRelationship.aliasTarget/>();
	}
   	</#if>


	<#if !util.isInheritedRelation(relation)>
    /**
     * Sets the <@childLowPlural/>
     * @param orders The <@childLowPlural/> to set.
     */
    public void set<@pluralCap relation.aliasTarget/>(List<<@childCap/>> <@pluralUncap relation.aliasTarget/>) {
        this.<@pluralUncap relation.aliasTarget/> = <@pluralUncap relation.aliasTarget/>;
    }
    
    /**
     * Adds one <@childLow/>
     * @param orders The <@childLow/> to add.
     */
    public boolean add<@cap relation.aliasTarget/>(<@childCap/> <@pluralUncap relation.aliasTarget/>) {
        return this.get<@pluralCap relation.aliasTarget/>().add(<@pluralUncap relation.aliasTarget/>);   
    }
   	</#if>
    
</@isNotInherited>
</@OTMRelationshipsLoop> 

<#-- Loop to handle Getters and Setters -->
<#-- <1:M with BO in the To position-->
<#-- <EXAMPLE Order (this) from Customer-->
<@OTMRelationshipsLoopInverse>
<@isNotInherited bo, relation>
<#if !util.isInheritedRelation(relation)>
    /**
     * Returns the <@parentLow/>
     * 
     * @return <@parentCap/> value of customer
     */
    @ManyToOne(cascade = { CascadeType.REFRESH })
	@JoinColumn(name = "<@uncap relation.aliasSource/>_<@uncap relation.aliasTarget/>_guid")
    @ClonePolicy(type = ClonePolicy.TYPE.None)
    public <@parentCap/> get<@cap relation.aliasSource/>() {
        return <@uncap relation.aliasSource/>;
    }

    /**
     * Sets the <@parentLow/>
     * @param <@parentCap/> The <@parentLow/> to set.
     */
    public void set<@cap relation.aliasSource/>(<@parentCap/> <@uncap relation.aliasSource/>) {
        this.<@uncap relation.aliasSource/> = <@uncap relation.aliasSource/>;
    }
</#if>
</@isNotInherited>
</@OTMRelationshipsLoopInverse>
<#-- 1:M End -->

<#-- M:1 Start -->

<#-- Loop to handle Getters and Setters -->
<#-- <M:1 with BO in the SOURCE position-->
<#-- <EXAMPLE Employee (this) has a SINGLE Title 
			or Address (this) has a single State-->
<@MTORelationshipsLoop>
<@isNotInherited bo, relation>
    /**
     * Returns the <@childLow/>
     * 
     * @return <@childCap/> value
     */
    @ManyToOne
	@JoinColumn(name = "<@uncap relation.aliasSource/>_<@uncap relation.aliasTarget/>_guid")
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@boCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@childCap/>.class, type = RelationshipInfo.TYPE.ManyToOne, direction = RelationshipInfo.DIRECTION.Bidirectional, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.Reference)
    public <@childCap/> get<@cap relation.aliasTarget/>() {
        return <@uncap relation.aliasTarget/>;
    }

    /**
     * Sets the <@childLow/>
     * @param <@childCap/> The <@childLow/> to set.
     */
    public void set<@cap relation.aliasTarget/>(<@childCap/> <@uncap relation.aliasTarget/>) {
        this.<@uncap relation.aliasTarget/> = <@uncap relation.aliasTarget/>;
    }
</@isNotInherited>
</@MTORelationshipsLoop>

<#-- Loop to handle Getters and Setters -->
<#-- <M:1 with BO in the TARGET position-->
<#-- <EXAMPLE Employee has a SINGLE Title (this) -->
<@MTOInverseRelationshipsLoop>
<@isNotInherited bo, relation>
    /**
     * Returns the <@parentLowPlural/>.
     *
     * @return List value of <@parentLowPlural/>
     */
    @OneToMany(mappedBy = "<@uncap relation.aliasTarget/>")
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@childCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@parentCap/>.class, type = RelationshipInfo.TYPE.OneToMany, direction = RelationshipInfo.DIRECTION.Bidirectional, inverse = true, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.None)
    public List<<@parentCap/>> get<@pluralCap relation.aliasSource/>() {
        return this.<@pluralUncap relation.aliasSource/>;
    }
    
    public void set<@pluralCap relation.aliasSource/>(List<<@parentCap/>> <@pluralUncap relation.aliasSource/>) {
        this.<@pluralUncap relation.aliasSource/> = <@pluralUncap relation.aliasSource/>;
    }
</@isNotInherited>
</@MTOInverseRelationshipsLoop>
<#-- M:1 End -->

<#-- 1:1 Start -->

<#-- Loop to handle Getters and Setters -->
<#-- <1:1 with this BO in the SOURCE position-->
<#-- <EXAMPLE Company (this) has a SINGLE TickerSymbol -->
<@OTORelationshipsLoop>
<@isNotInherited bo, relation>
    /**
     * Returns the <@childLow/>
     * 
     * <#-- NOTE: Hibernate 1-to-1 parent-to-child relationships look like M:1 relationships w/ a unique contraint -->
     *
     * @return <@childCap/> value
     */
    @OneToOne(cascade = { CascadeType.ALL })
    @JoinColumn(name = "<@uncap relation.aliasSource/>_<@uncap relation.aliasTarget/>_guid", nullable = true)
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@boCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@childCap/>.class, type = RelationshipInfo.TYPE.OneToOne, direction = RelationshipInfo.DIRECTION.Bidirectional, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.Traverse)
    public <@childCap/> get<@cap relation.aliasTarget/>() {
        return <@uncap relation.aliasTarget/>;
    }

    /**
     * Sets the <@childLow/>
     * @param <@childCap/> The <@childLow/> to set.
     */
    public void set<@cap relation.aliasTarget/>(<@childCap/> <@uncap relation.aliasTarget/>) {
        this.<@uncap relation.aliasTarget/> = <@uncap relation.aliasTarget/>;
    }
</@isNotInherited>
</@OTORelationshipsLoop>

<#-- Loop to handle Getters and Setters -->
<#-- <1:1 with this BO in the TARGET position-->
<#-- <EXAMPLE TickerSymbol (this) has a SINGLE Company -->
<@OTOInverseRelationshipsLoop>
<@isNotInherited bo, relation>
    /**
     * Returns the <@parentLow/>.
     *
     * @return <@parentLow/> value.
     *
     */
	@OneToOne(mappedBy = "<@uncap relation.aliasTarget/>", cascade = { CascadeType.REFRESH })
    @RelationshipInfo(displayKey = "${relation.display}", parent = <@childCap/>.class, parentAlias = "<@uncap relation.aliasSource/>", childAlias = "<@uncap relation.aliasTarget/>", child = <@parentCap/>.class, type = RelationshipInfo.TYPE.OneToOne, direction = RelationshipInfo.DIRECTION.Bidirectional, inverse = true, internalized = <@internalized/>)
    @DisplayName(name = "${relation.display}")
    @ClonePolicy(type = ClonePolicy.TYPE.None)
    public <@parentCap/> get<@cap relation.aliasSource/>() {
        return this.<@uncap relation.aliasSource/>;
    }
    
    public void set<@cap relation.aliasSource/>(<@parentCap/> <@uncap relation.aliasSource/>) {
        this.<@uncap relation.aliasSource/> = <@uncap relation.aliasSource/>;
    }
</@isNotInherited>
</@OTOInverseRelationshipsLoop>
<#-- 1:1 End -->

<@abstactMethod bo>
	/**
	 * ${method.desc}
	 */
	@Transient
	public abstract ${method.returns} ${method.name}(${method.params});

</@abstactMethod>

	// @SNIPPET@

}
